/**
 * @addtogroup brd_ext_int
 * brd_ext_int
 * @{
 */
/**
 * @file brd_ext_int.h
 * @brief 外部中断板级层
 * @par 修改日志
 * <table>
 * <tr><th>Date <th>Version <th>Author <th>Description
 * <tr><td>2020-09-30 <td>1.0 <td>软件工程院 <td>创建初始版本
 * @par 示例
 * @code
 * 创建设备, 多个中断可以同时打开.
   Brd_TExtIntIrqFlag flag;
   Brd_THandle hande = Brd_ExtIntCreate(0);
   ...
   /// 休眠模式下使用示例
   /// 关闭总中断
   Brd_DisableGlobalIrq();
   ...
   Brd_ExtIntOpen(handle);
   ...
   WFI();
   flag = Brd_ExtIntIrqFlag();
   ...
   Brd_ExtIntClose(handle);
   ...
   /// 开启总中断
    Brd_EnableGlobalIrq();
   ...
 * @endcode
 * @copyright 杭州鸿泉物联网技术股份有限公司
 */

#ifndef _BRD_EXT_INT_H_
#define _BRD_EXT_INT_H_

#include <ofc_types.h>
#include "brd_common.h"
#include "brd_def.h"

#ifdef __linux
#pragma GCC visibility push(default)
#endif 

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 根据标识创建句柄
 * @param id: 标识, 参见[brd_def](@ref Brd_TExtIntIdTag)
 * @return 当返回值为非 NULL 时, 表示创建成功, \n
 *         当返回值为 NULL 时, 表示创建失败, 原因为参数错误
 */
Brd_THandle Brd_ExtIntCreate(Int32 id);

/**
 * 释放句柄
 * @param handle: 句柄
 * @return 无返回值
 */
void Brd_ExtIntFree(Brd_THandle handle);

/**
 * 获取标识
 * @param handle: 句柄
 * @return 返回用于创建句柄的标识
 */
Int32 Brd_ExtIntId(Brd_THandle handle);

/**
 * 中断事件
 * @note: 由中断中调用, 当禁止全局中断时, 将不会该事件
 * @param sender: 事件的产生者
 * @return 无返回值
 */
typedef void (*Brd_TOnExtIntIrq)(Brd_THandle handle);

/**
 * 获取事件接收者
 * @param handle: 句柄
 * @return 当返回值为非 NULL 时, 表示事件接收者 \n
 *         当返回值为 NULL 时, 表示未设置过事件接收者
 */
void *Brd_ExtIntEventReceiver(Brd_THandle handle);

/**
 * 设置事件接收者
 * @param handle: 句柄
 * @param receiver: 事件接收者
 * @return 无返回值 
 */
void Brd_ExtIntSetEventReceiver(Brd_THandle handle, void *receiver);

/**
 * 设置中断事件
 * @param handle: 句柄
 * @param on_event: 事件方法, 在本方法中不能执行耗时长的动作
 * @return 无返回值 
 */
void Brd_ExtIntSetOnIrq(Brd_THandle handle, Brd_TOnExtIntIrq on_event);

/**
 * 设置中断产生的方式
 * @note 当设置了中断事件, 并设置为持续产生模式, 需要用户在中断事件中调用 Brd_ExtIntClose
 *    -# 关闭中断, 否则系统将一直被中断抢占, 如果启动了看门狗, 会导致系统复位
 *    -# 持续模式一般在休眠唤醒中使用, 常为电平方式检测中断, 用于防止系统错过触发边沿
 *    -# 本函数需要在 Brd_ExtIntOpen 之前使用
 * @param handle: 句柄
 * @param permanent: True 持续的产生中断, False 只产生一次中断
 * @return 无返回值 
 */
void Brd_ExtIntSetMode(Brd_THandle handle, Bool permanent);

/**
 * 打开中断
 * @param handle: 句柄
 * @return 当返回值 >= 0 时, 表示设置成功 \n
 *         当返回值 < 0 时, 表示设置失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_ExtIntOpen(Brd_THandle handle);

/**
 * 关闭中断
 * @param handle: 句柄
 * @return 当返回值 >= 0 时, 表示设置成功 \n
 *         当返回值 < 0 时, 表示设置失败参见[brd_def](@ref Brd_TErrorCodeTag)
 */
Int32 Brd_ExtIntClose(Brd_THandle handle);

/**
 * 获取唤醒中断标志
 * @note 
 *  - 常用于设备休眠并禁止全局中断时, 用户可以在全局中断打开前
 *  - 读取标志值, 查询是否有唤醒源触发了中断
 * @param handle: 句柄
 * @return 返回 True, 表示有中断产生 \n
 *         返回 False, 表示无中断产生
 */
Bool Brd_ExtIntIrqFlag(Brd_THandle handle);

#ifdef __cplusplus
}  ///< extern "C"
#endif

#ifdef __linux
#pragma GCC visibility pop
#endif 

#endif // _BRD_EXT_INT_H_
/**
 * @} 
 */
